const FirstData = [
{
title: 'Title 1',
data: ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'],
},
{
title: 'Title 2',
data: ['a', 'b', 'c'],
},
{
title: 'Title 3',
data: ['hello1', 'hello2', 'hello3', 'hello4', 'hello5'],
},
];
SecondData's data is shuffled behind the scene
const SecondData = [
{
title: 'Title 1',
data: ['foo3', 'foo1', 'foo2'],
},
{
title: 'Title 2',
data: ['b', 'c', 'a'],
},
{
title: 'Title 3',
data: ['hello1', 'hello3', 'hello2'],
},
];
EXPECTED OUTPUT (Must be similar to SecondData but the new strings from FirstData's data must be pushed, added or merged):
[
{
title: 'Title 1',
data: ['foo3', 'foo1', 'foo2', 'foo4', 'foo5'],
},
{
title: 'Title 2',
data: ['b', 'c', 'a'],
},
{
title: 'Title 3',
data: ['hello1', 'hello3', 'hello2', 'hello4', 'hello5'],
},
];
You could create a map that indexes based on title and then use Set to make sure that you don't add duplicates. Something like this:
const items = {}
firstData.forEach(item => {
items[item.title] = new Set([...item.data)]
})
secondData.forEach(item => {
const existingItem = items[item.title]
if(!existingItem) {
items[item.title] = new Set([...item.data)]
} else {
items[item.title] = new Set([...existingItem, ...item.data])
}
})
const merged = Object.keys(items).map(title => ({
title: key,
data: [...items[key]]
})
)
I would suggest concatenating the arrays, then using Array.reduce() to group the values by title.
For each entry, we merge the data array using a Set, which will discard any duplicate values in this array.
const FirstData = [ { title: 'Title 1', data: ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'], }, { title: 'Title 2', data: ['a', 'b', 'c'], }, { title: 'Title 3', data: ['hello1', 'hello2', 'hello3', 'hello4', 'hello5'], }, ];
const SecondData = [ { title: 'Title 1', data: ['foo3', 'foo1', 'foo2'], }, { title: 'Title 2', data: ['b', 'c', 'a'], }, { title: 'Title 3', data: ['hello1', 'hello3', 'hello2'], }, ];
// Concatenate our data to get input...
const input = FirstData.concat(SecondData);
// Group each item by title.
// For each item, merge the data array using a Set object
const result = Object.values(input.reduce((acc, { title, data }) => {
acc[title] = acc[title] || { title, data: [] };
acc[title].data = [...new Set([...acc[title].data, ...data])];
return acc;
}, {}));
console.log('Result:', result)
You could take a Set and filter the given array from random values.
const
merge = (a, b) => [
...a,
...b.filter((s => v => !s.has(v))(new Set(a)))
],
given = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'],
random = ['foo3', 'foo1', 'foo2'],
result = merge(random, given);
console.log(...result);